//
// Created by sri01 on 2025/11/4.
//

#ifndef MOTORBLDC_H
#define MOTORBLDC_H

#include "Foc_math.h"
#include "MT6816.h"
#include "foc_hall.h"
#include "foc_hfi.h"
#include "foc_smo.h"
#include "foc_vf.h"
#include "pid.h"

#define L  (6.05f / 1000000.0f) /* 6.05uH */
#define R  (68.0f / 1000.0f)    /* 68 mΩ */
/* 磁通: 0.600 mWb */
#define Tc L / R / 10.0f

#define TIMER1_CLK_MHz         168                                        // 定时器时钟频率
#define PWM_FREQUENCY          20000                                      // PWM频率20KHz
#define PWM_MEASURE_PERIOD     (float)(1.0f / (float)PWM_FREQUENCY)       // PWM周期
#define CURRENT_MEASURE_HZ     PWM_FREQUENCY                              // 电流频率
#define CURRENT_MEASURE_PERIOD (float)(1.0f / (float)CURRENT_MEASURE_HZ)  // 电流周期
#define PWM_PERIOD_CYCLES                                                                                              \
    (uint16_t)((TIMER1_CLK_MHz * (uint32_t)1000000u / ((uint32_t)(PWM_FREQUENCY))) & 0xFFFE)  // 定时器1的周期数
#define PWM_ARR (uint16_t)(PWM_PERIOD_CYCLES / 2u)

typedef enum
{
    Encoder_MT6816 = 0,
    Encoder_Hall,
    Sensorless_HFT,
    Sensorless_SMO,
    Sensorless_VF,
} ElAngle_Get_t;

typedef struct
{
    I_adc_t I_adc;
    I_alphabeta_t I_alphabeta;
    I_dq_t I_dq;
} BLDC_IN_t;

typedef struct
{
    V_dq_t V_dq;
    V_alphabeta_t V_alphabeta;
    V_adc_t V_adc;
    V_adc_t V_dtc;
} BLDC_OUT_t;

typedef struct
{
    ElAngle_Get_t ElAngle_Get;
    MT6816_t MT6816;
    FOC_HALL_t FOC_HALL;
    FOC_HFI_t FOC_HFI;
    FOC_SMO_t FOC_SMO;
    FOC_VF_t FOC_VF;
    Circular_t Circular;
} BLDC_Data_t;

typedef struct
{
    BLDC_IN_t BLDC_IN;
    BLDC_OUT_t BLDC_OUT;
    BLDC_Data_t BLDC_Data;
    Encoder_t Encoder;
    PidTypeDef Pid_D;
    PidTypeDef Pid_Q;
} Motor_Cur_t;

typedef struct
{
    float Position;
    float Speed;
    float Current;
    float Output;
} Cur_Data_t;

typedef struct
{
    Cur_Data_t Cur_Data;
    PidTypeDef Pid_S;
    PidTypeDef Pid_P;
} Motor_App_t;

void FOC_Current(Motor_Cur_t* Motor_Cur, float Id_set, float Iq_set);
Cur_Data_t GetMotorData(BLDC_Data_t* BLDC_Data, float Current);
uint8_t FOC_PosVel(Motor_App_t* Motor_App, float* Pos_set, float* Vel_max);

#endif  // MOTORBLDC_H
